package com.winit.openapi.tms.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.vo.Bpartner;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.tms.builder.BookingLogisticsWarehouseBuilder;
import com.winit.openapi.tms.builder.BookingOrderBuilder;
import com.winit.openapi.tms.constant.BookingConstant;
import com.winit.openapi.tms.validator.BookingOrderValidator;
import com.winit.tms.spi.booking.WarehouseInBookingOrderService;
import com.winit.tms.spi.booking.WarehouseinRuleUnloadTypeService;
import com.winit.tms.spi.booking.command.WarehouseInBookingOrderCancelCommand;
import com.winit.tms.spi.booking.command.WarehouseInBookingOrderCommand;
import com.winit.tms.spi.booking.command.WarehouseInBookingOrderQueryCommand;
import com.winit.tms.spi.booking.command.WarehouseinRuleUnloadTypeQueryCommand;
import com.winit.tms.spi.booking.vo.BookingLogisticsWarehouseVo;
import com.winit.tms.spi.booking.vo.BookingOrderCancelValidateVo;
import com.winit.tms.spi.booking.vo.BookingOrderOrLogisticsWarehouseVo;
import com.winit.tms.spi.booking.vo.WarehouseInBookingOrderDetailsVo;
import com.winit.tms.spi.booking.vo.WarehouseInBookingOrderVo;
import com.winit.tms.spi.booking.vo.WarehouseinRuleUnloadTypeVo;

/**
 * 预约单Controller
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * ming.chen 	1.0  		2017-9-8 	Created
 * 
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "/tms/bookingOrder")
public class BookingOrderController extends BaseController {

    @Resource
    private WarehouseInBookingOrderService warehouseInBookingOrderService;
    @Resource
    private WarehouseinRuleUnloadTypeService warehouseinRuleUnloadTypeService;

    /**
     * 获取预约单列表
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/queryBookingOrderList")
    public String queryBookingOrderList(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        WarehouseInBookingOrderQueryCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = BookingOrderBuilder.buildQueryCommand(json);
            Searchable searchable = buildSearchablePageParams(json);
            searchable.addSort(new Sort(Direction.DESC, "CREATED"));
            command.setSearchable(searchable);
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        Page<WarehouseInBookingOrderVo> page = warehouseInBookingOrderService.queryBookingOrderListAsOpenapi(command);
        Map<String, Object> data = new HashMap<String, Object>();
        responseMsg.setData(data);
        if (page != null) {
            Map<String, Object> pageMap = getPageParams(page);
            data.put("list", BookingOrderBuilder.buildReturnWarehouseInBookingOrderList(page.getContent()));
            data.put("pageParams", pageMap.get("pageParams"));
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 获取预约单详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getOrderByBookingNo")
    public String getOrderByBookingNo(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        WarehouseInBookingOrderQueryCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = new WarehouseInBookingOrderQueryCommand();
            if (json.containsKey("bookingNo")) {
                command.setBookingNo(json.getString("bookingNo"));
            }
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        WarehouseInBookingOrderDetailsVo vo = warehouseInBookingOrderService.getBookingOrderByBookingNo(command);

        Map<String, Object> map = new HashMap<String, Object>();
        if (vo != null) {
            map = BookingOrderBuilder.buildReturnBookingOrderInfoForAPI(vo);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 新增预约单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/createWarehouseInBookingOrder")
    public String createWarehouseInBookingOrder(@ModelAttribute RequestMsg requestMsg,
                                                @ModelAttribute ResponseMsg responseMsg) {
        WarehouseInBookingOrderCommand command = null;
        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            // 新增预约单字段校验
            BookingOrderValidator.validCreateBookingOrderField(json);

            command = new WarehouseInBookingOrderCommand();
            WarehouseInBookingOrderVo bookingOrderVo = BookingOrderBuilder.buildBookingOrderVo(json,
                requestMsg.getPlatform());

            // 获取客户信息
            String customerCode = null;
            String customerName = null;
            // 来源卖家网站
            if (BookingConstant.SourceType.SW.getType().equals(requestMsg.getPlatform())) {
                Bpartner bpartner = CommandContext.getContext().get(ApiConstant.API_BPARTNER);
                customerCode = bpartner.getValue();
                customerName = bpartner.getName();
            }
            // 数据来源booking
            else if (BookingConstant.SourceType.BK.getType().equals(requestMsg.getPlatform())) {
                customerCode = "winit";
                customerName = "WINIT";
            }
            bookingOrderVo.setCustomerCode(customerCode);
            bookingOrderVo.setCustomerName(customerName);
            command.setWarehouseInBookingOrderVo(bookingOrderVo);
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        String bookingNo = warehouseInBookingOrderService.createWarehouseInBookingOrder(command);

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("bookingNo", bookingNo);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 修改预约单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updateWarehouseInBookingOrder")
    public String updateWarehouseInBookingOrder(@ModelAttribute RequestMsg requestMsg,
                                                @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        WarehouseInBookingOrderCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = new WarehouseInBookingOrderCommand();
            WarehouseInBookingOrderVo bookingOrderVo = BookingOrderBuilder.buildBookingOrderVo(json,
                requestMsg.getPlatform());
            command.setWarehouseInBookingOrderVo(bookingOrderVo);
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        String bookingNo = warehouseInBookingOrderService.updateWarehouseInBookingOrder(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("bookingNo", bookingNo);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 取消预约单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/cancelWarehouseInBookingOrder")
    public String cancelWarehouseInBookingOrder(@ModelAttribute RequestMsg requestMsg,
                                                @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        WarehouseInBookingOrderCancelCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = new WarehouseInBookingOrderCancelCommand();
            if (json.containsKey("bookingNo")) {
                command.setBookingNo(json.getString("bookingNo"));
            }
            if (json.containsKey("bookingCode")) {
                command.setBookingCode(json.getString("bookingCode"));
            }
            command.setSource(requestMsg.getPlatform());
            command.setCtx(CommandContext.getContext());
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        String bookingNo = warehouseInBookingOrderService.cancelWarehouseInBookingOrder(command);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("bookingNo", bookingNo);
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 根据预约单号/预约码获取相关信息
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/getBookingOrder")
    public String getBookingOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        WarehouseInBookingOrderQueryCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = new WarehouseInBookingOrderQueryCommand();
            if (json.containsKey("documentNo")) {
                command.setDocumentNo(json.getString("documentNo"));
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        BookingOrderOrLogisticsWarehouseVo vo = warehouseInBookingOrderService.getBookingOrder(command);

        List<WarehouseInBookingOrderDetailsVo> warehouseInBookingOrderDetailsVoList = vo.getWarehouseInBookingOrderDetailsVoList();
        List<BookingLogisticsWarehouseVo> bookingLogisticsWarehouseVoList = vo.getBookingLogisticsWarehouseVoList();

        Map<String, Object> map = new HashMap<String, Object>();

        List<Map<String, Object>> orderDetailsVoList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> logisticsWarehouseList = new ArrayList<Map<String, Object>>();

        if (CollectionUtils.isNotEmpty(warehouseInBookingOrderDetailsVoList)) {
            for (WarehouseInBookingOrderDetailsVo detailsVo : warehouseInBookingOrderDetailsVoList) {
                orderDetailsVoList.add(BookingOrderBuilder.buildReturnBookingOrderInfoForAPI(detailsVo));
            }
        }

        if (CollectionUtils.isNotEmpty(bookingLogisticsWarehouseVoList)) {
            for (BookingLogisticsWarehouseVo warehouseVo : bookingLogisticsWarehouseVoList) {
                logisticsWarehouseList.add(BookingLogisticsWarehouseBuilder.buildReturnLogisticsWarehouse(warehouseVo));
            }
        }

        if (CollectionUtils.isNotEmpty(orderDetailsVoList)) {
            map.put("warehouseInBookingOrderDetailsVoList", orderDetailsVoList);
        }
        if (CollectionUtils.isNotEmpty(logisticsWarehouseList)) {
            map.put("bookingLogisticsWarehouseVoList", logisticsWarehouseList);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }

    /**
     * 取消预约单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/isOvertime")
    public String validateIsOvertime(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        Object obj = requestMsg.getData();
        WarehouseInBookingOrderQueryCommand command = null;
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = new WarehouseInBookingOrderQueryCommand();
            String bookingNo = json.getString("bookingNo");
            if (StringUtils.isEmpty(bookingNo)) {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL, "warehouseCode");
            }
            command.setBookingNo(bookingNo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        BookingOrderCancelValidateVo vo = warehouseInBookingOrderService.validateIsOvertimeCancel(command);
        Map<String, Object> map = new HashMap<String, Object>();
        if (vo != null) {
            map = BookingOrderBuilder.buildReturnBookingOrderCancelValidateVo(vo);
        }
        responseMsg.setData(map);
        return SUCCESS;
    }
    
    @RequestMapping(value = "/getUnloadTypeByWarehouseCode")
    public String getUnloadTypeByWarehouseCode(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg){
        Object obj = requestMsg.getData();
        WarehouseinRuleUnloadTypeQueryCommand command = null;
        
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            command = new WarehouseinRuleUnloadTypeQueryCommand();
            WarehouseinRuleUnloadTypeVo vo = new WarehouseinRuleUnloadTypeVo();
            String warehouseCode = json.getString("warehouseCode");
            if (StringUtils.isEmpty(warehouseCode)) {
                throw new ApiException(ErrorCode.FIELD_NOT_NULL, "warehouseCode");
            }
            vo.setWarehouseCode(warehouseCode);
            command.setVo(vo);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        List<WarehouseinRuleUnloadTypeVo> result = warehouseinRuleUnloadTypeService.queryWarehouseinRuleUnloadTypeList(command);
        Map<String, Object> map = new HashMap<String, Object>();
        if (CollectionUtils.isNotEmpty(result)){
            map.put("unloadTypeList", BookingOrderBuilder.buildReturnWarehouseinRuleUnloadType(result));
        }
        responseMsg.setData(map);
        return SUCCESS;
    }
}
